package com.donglan.pethome.pay.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.donglan.pethome.basic.util.QuartzUtils;
import com.donglan.pethome.order.domain.OrderAdopt;
import com.donglan.pethome.order.mapper.OrderAdoptMapper;
import com.donglan.pethome.pay.constant.AlipayConfig;
import com.donglan.pethome.pay.constant.PayConstants;
import com.donglan.pethome.pay.domain.AlipayInfo;
import com.donglan.pethome.pay.domain.PayBill;
import com.donglan.pethome.pay.mapper.AlipayInfoMapper;
import com.donglan.pethome.pay.mapper.PayBillMapper;
import com.donglan.pethome.pay.service.PayBillService;
import com.donglan.pethome.quartz.service.QuartzService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * @Author: zhangdonghui
 * @Date: 2022/3/2 20:40
 * 支付
 */
@Service
public class PayBillServiceImpl implements PayBillService {

    @Autowired
    private AlipayInfoMapper alipayInfoMapper;

    // 支付单mapper
    @Autowired
    private PayBillMapper payBillMapper;
    // 领养订单mapper
    @Autowired
    private OrderAdoptMapper orderAdoptMapper;
    // 定时业务
    @Autowired
    private QuartzService quartzService;


    /*
     * 功能描述 请求支付宝返回的html数据的字符串,跳转到支付界面
     * @author zhangdonghui
     * @date 2022/3/2 21:03
     * @param orderAdopt 领养订单
     * @return java.lang.String
     */
    @Override
    public String goPay(OrderAdopt orderAdopt) {

        try {
            // 获取支付信息对象
            AlipayInfo alipayInfo = alipayInfoMapper.loadByShopId(orderAdopt.getShop().getId());

            // 获得初始化的AlipayClient，我们可以通过店铺id，获取到appid和私钥，因为一个支付信息对应一个店铺，所以需要Alipay
            AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, alipayInfo.getAppid(),
                    alipayInfo.getMerchant_private_key(), "json", AlipayConfig.charset,
                    alipayInfo.getAlipay_public_key(), AlipayConfig.sign_type);

            // 设置请求参数
            AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
            // 设置同步请求
            alipayRequest.setReturnUrl(AlipayConfig.return_url);
            // 设置异步请求
            alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

            //商户订单号，商户网站订单系统中唯一订单号，必填
            String out_trade_no = orderAdopt.getOrderSn();
            //付款金额，必填
            String total_amount = orderAdopt.getPrice().toString();
            //订单名称，必填
            String subject = orderAdopt.getDigest();// 使用摘要代替
            //商品描述，可空
            String body = orderAdopt.getDigest();// 使用摘要代替

            alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                    + "\"total_amount\":\""+ total_amount +"\","
                    + "\"subject\":\""+ subject +"\","
                    + "\"body\":\""+ body +"\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

            //请求
            String result = alipayClient.pageExecute(alipayRequest).getBody();
            return result;
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "";
        }

        //return null;
    }

    /*
     * 功能描述 处理订单，修改状态并且填充数据
     * @author zhangdonghui
     * @date 2022/3/8 11:13
     * @param out_trade_no 领养订单编号的商品订单
     * @param trade_no 支付交易单的交易号
     * @return void
     */
    @Override
    @Transactional
    public String handleOrder(String out_trade_no, String trade_no) {
        // 根据订单编号查询支付单对象
        PayBill payBill = payBillMapper.loadByOrderSn(out_trade_no);
        // 判断状态
        if(payBill.getState() != 0){
            // 表示已经处理过，就不能在联系进行第二次
            return "failure";
        }
        // 支付成功
        payBill.setState(1);
        // 记录支付成功的时间
        payBill.setUpdateTime(new Date());
        // 设置支付宝的交易号
        payBill.setUnionPaySn(trade_no);
        // 修改payBill对象
        payBillMapper.update(payBill);

        // 继续修改订单的状态 定位我们需要操作的是哪一张表
        switch (payBill.getBusinessType()){
            // 定位我们操作到领养订单
            case PayConstants.BUSINESSTYPE_ADOPT:
                // 根据订单编号查询领养订单对象
                //OrderAdopt orderAdopt = orderAdoptMapper.loadByOrderSn(out_trade_no);
                // 根据领养订单id获取领养订单对象【和上面作用一样】
                OrderAdopt orderAdopt = orderAdoptMapper.loadById(payBill.getBusinessKey());
                orderAdopt.setState(1);// 领养订单状态
                orderAdopt.setPaySn(trade_no);// 领养订单中的交易号，实际上该字段可写可不写
                orderAdoptMapper.update(orderAdopt);
                // 删除定时任务
                quartzService.removeJob(PayConstants.BUSINESSTYPE_ADOPT+out_trade_no);
                break;
            case PayConstants.BUSINESSTYPE_GOODS:
                break;
            case PayConstants.BUSINESSTYPE_PRODUCT:
                break;
        }
        return "success";
    }

}
